home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_077 / language.doc / drio.ref < prev    next >
Text File  |  1992-05-06  |  12KB  |  232 lines

  1. XIV. The Draco I/O System
  2.  
  3.     Draco now has a formal I/O system based on new 'read' and 'write'
  4.     constructs added to the language. These constructs are modelled on
  5.     those of Pascal, but that language's problems with error handling and
  6.     interactive I/O have been overcome. Simple output to the terminal is
  7.     done using the 'write' and 'writeln' statements. 'writeln' is identical
  8.     to 'write' except that it finishes one "line" of output and starts the
  9.     next. On line-oriented systems such as MTS, the destinction between
  10.     'write' and 'writeln' is much more significant.
  11.  
  12.     'write' takes each one of it's arguments and writes them on the
  13.     terminal in text form. The following types can be output in this way:
  14.     all numeric values, character values, single dimension arrays of
  15.     characters, pointer to character ('chars') strings, and I/O channels
  16.     (the associated file name, if any, is written). Numeric output by
  17.     default uses as few characters as possible to output the value - there
  18.     are no leading or trailing spaces. Numeric output can be signed, or
  19.     unsigned in decimal, hexadecimal, octal or binary format. 8 bit values
  20.     are supported directly, i.e. they are not converted to 16 bit values
  21.     before output.
  22.  
  23.     The default format for numeric values is signed decimal for signed
  24.     values, and unsigned decimal for unsigned values. A different format
  25.     can be specified by following the numeric expression with a colon and a
  26.     format specifier (i for signed, u for unsigned decimal, x for
  27.     hexadecimal, o for octal or b for binary). A fixed field width can be
  28.     specified by appending a colon and a numeric expression after the value
  29.     or after the format specification. In case of ambiguity (e.g. variable
  30.     'i' contains the desired field length), the length can be in
  31.     parentheses. The output will be right justified in a field of the
  32.     required length. If the length is negative, the field will be filled
  33.     with leading zeros instead of spaces.
  34.  
  35.     For example, assuming the values
  36.  
  37.         i : 123
  38.         j : 12
  39.         n : 60528
  40.         w : 0xabc
  41.  
  42.     the write statement
  43.  
  44.         write(i, n : u, ' ', w:x:-4, i:j)
  45.  
  46.     will produce the following output: (blanks are represented by '_'s)
  47.  
  48.         12360528_0abc_________123
  49.  
  50.     Input is done using the 'read' and 'readln' constructs. No field width
  51.     specification is allowed, however (fixed format input is for the stone
  52.     ages). When reading numerics, spaces and tabs are skipped as necessary.
  53.     Reading continues with all digits which are valid for the base being
  54.     used. Either lower case or upper case is accepted for hexadecimal
  55.     digits. If the current input line does not contain the required data,
  56.     the next input line will NOT be automatically read; instead, the input
  57.     channel will be flagged as having an error (more on that later).
  58.  
  59.     When reading arrays of characters, single characters will be read from
  60.     the input as needed until the entire array is filled or the end of the
  61.     line is reached. If the end of the line is reached, the remainder of
  62.     the array is filled with blanks. When reading a character pointer
  63.     value ('chars' value), the remainder of the current input line (if any)
  64.     is read into the pointed-to region and is terminated by a '\e'. The
  65.     input region is assumed to be long enough. Thus, reading a 'chars'
  66.     value after doing a 'readln' will read the entire next input line.
  67.  
  68.     I/O defaults to the user's terminal, but can be to/from other places
  69.     through the use of channels. A channel is strictly typed as either
  70.     input or output and either text or binary. Channels are a new data type
  71.     in Draco and can be used as all other types. A channel type consists of
  72.     the word 'channel', followed by one of 'input' or 'output', followed by
  73.     one of 'text' or 'binary'. Such channels can be used with read/write by
  74.     giving a channel expression (usually just the name of a declared
  75.     channel variable) followed by a semicolon, before any of the values to
  76.     be read/written. One of the sources/destinations is a file. Files
  77.     consist of some data structures used by the I/O routines, and a buffer
  78.     whose size is specified by the programmer. A file type consists of the
  79.     word 'file' followed by a parenthesized value giving the size in
  80.     characters (bytes) of the desired buffer. The actual size will be
  81.     rounded up as required by the host operating system (to the nearest 128
  82.     for CP/M). If no value is given within the parentheses, a minimum
  83.     default value will be used. Each file variable can be used as either an
  84.     input source or an output sink, but not as both at the same time.
  85.  
  86.     Text channels convert internal representations to/from character form
  87.     and can only be used with the types given earlier. Binary channels can
  88.     be used with any type, and do no conversions whatever on the values
  89.     read or written. Note that transitory values such as pointers, channels
  90.     and files cannot normally be properly saved and restored between runs.
  91.  
  92.     Channels must be initialized with the 'open' construct before they can
  93.     be used. There are different forms of 'open' for different kinds of
  94.     channels. The open construct consists of the word 'open'; followed by a
  95.     left parenthesis; an expression giving the channel to be opened; and
  96.     0, 1 or 2 additional parameters, all separated by commas; and a closing
  97.     right parenthesis. A corresponding 'close' construct is passed only the
  98.     channel to be closed, all other information has been preserved within
  99.     the channel itself. All channels that a program opens must be closed by
  100.     that program. (Closing input channels isn't necessary on some systems,
  101.     but it doesn't hurt, and it aids porting to systems that do care.)
  102.     NOTE: AmigaDOS cares!!!!
  103.  
  104.     If no additional parameters are given to 'open', then the channel is
  105.     connected to the user's terminal (this provides a way to get normal
  106.     I/O, but through an explicit channel). A channel can be connected to a
  107.     memory buffer by providing a character pointer ('chars' value) as a
  108.     second parameter. The pointed-to buffer is then considered to be a file
  109.     of text and may contain several lines, separated by carriage-returns
  110.     and/or linefeeds. Such a buffer used for output is assumed to be large
  111.     enough for whatever is output to it. When an output channel opened in
  112.     this way is closed, a '\e' is written to the end of the output buffer.
  113.     Only text channels can be connected to 'chars' values.
  114.  
  115.     The second parameter to 'open' can be a procedure which is to be used
  116.     to supply or consume the characters or bytes of data. A supplier
  117.     procedure must have no parameters and must return a character for text
  118.     input or a byte for binary input. A consumer procedure must have a
  119.     single character parameter for text output or a single byte parameter
  120.     for binary output. It must not return any result. Input text channels
  121.     internally buffer one character, so it is not necessary to have a way
  122.     to 'unread' a character. This buffering is done in such a way that
  123.     further input lines are not read until an explicit 'readln' is done,
  124.     thus allowing input from interactive terminals to operate correctly. As
  125.     an example, when doing numeric output within a program which uses
  126.     direct screen I/O through the 'CRT' library, a text output channel
  127.     which uses the 'CRT_PutChar' routine could be used to position output
  128.     on the screen.
  129.  
  130.     If the second parameter to 'open' is a file expression, then the third
  131.     parameter must be a 'chars' value supplying the name of the file to be
  132.     opened for I/O. The details of the filename will vary from system to
  133.     system.
  134.  
  135.     All of the I/O constructs in Draco return a bool (true/false) value
  136.     indicating whether or not they succeeded. In many cases (e.g. writing
  137.     to a 'chars' buffer or through a procedure), success is guaranteed, but
  138.     some cases provide opportunities for error. A channel which has had an
  139.     error cannot be used for further I/O; attempts to do so will result in
  140.     an error message from the I/O routines, and termination of the program.
  141.     The bool value returned by the I/O constructs is special to the compiler.
  142.     It can be ignored without the compiler complaining. Thus, the I/O
  143.     constructs can be either statements or boolean expressions.
  144.  
  145.     The language construct 'ioerror' can be used to determine the nature of
  146.     the error, and to reset the channel so that I/O can continue. The
  147.     open construct will only fail if the channel was being opened on a
  148.     file and the operating system could not open that file. The most common
  149.     reason for failure is the end of the input data on a 'read'. This can
  150.     mean the end of the phyical file when reading binary data, a logical or
  151.     physical end of file when reading text data, or the end of the string
  152.     when reading from a 'chars' value. The other common error is that of
  153.     bad data when reading numeric values from a text channel. If 'ioerror'
  154.     is given no parameter, then it returns/resets the error code of the
  155.     default terminal input text channel. Include file 'util.g' contains
  156.     definitions of the various values returned by 'ioerror', along with
  157.     declarations of several useful procedures available in the run-time
  158.     system.
  159.  
  160.     The following example illustrates many of the ideas discussed. It is a
  161.     small program which adds up 10 signed decimal integers entered from an
  162.     interactive terminal. The input numbers can be spread over as many
  163.     input lines as the user wishes. A prompt of '>' is given to the user.
  164.  
  165.     #util.g
  166.  
  167.     proc main()void:
  168.         int n, sum, i;
  169.  
  170.         sum := 0;
  171.         write('>');
  172.         for i from 1 upto 10 do
  173.         while
  174.             if read(n) then
  175.             /* got a number! */
  176.             false
  177.             else
  178.             case ioerror()
  179.             incase CH_EOF:
  180.                 writeln("*** You're not done yet! ***");
  181.             incase CH_MISSING:
  182.                 /* nothing left on this line */
  183.                 ;
  184.             default:
  185.                 writeln("*** Invalid number - keep going. ***");
  186.             esac;
  187.             write('>');
  188.             readln();
  189.             true
  190.             fi
  191.         do
  192.         od;
  193.         sum := sum + n;
  194.         od;
  195.         writeln("Sum = ", sum);
  196.     corp;
  197.  
  198.     A slightly smarter program would give more details about what was wrong
  199.     with the numbers (bad character - use character input to show it,
  200.     overflow), and would tell the user how many numbers were left to input.
  201.     The end-of-file condition can only be reset on terminal channels,
  202.     since when reading from files, procedures, etc. the run-time system has
  203.     no control over it. Input from a non-interactive source (e.g. a file)
  204.     is much simpler, in that the run-time system will automatically abort
  205.     the program on the next I/O request after an error. E.g. the following
  206.     program writes 100 numbers to a file, then reads them back into an
  207.     array;
  208.  
  209.     proc main()void:
  210.         file() f;
  211.         channel input text chin;
  212.         channel output text chout;
  213.         int i;
  214.         [100] int array;
  215.  
  216.         open(chout, f, "NUMBERS.DAT");
  217.         for i from 1 upto 100 do
  218.         write(chout; i, ' ');
  219.         od;
  220.         close(chout);
  221.         open(chin, f, "NUMBERS.DAT");
  222.         for i from 0 upto 99 do
  223.         read(chin; array[i]);
  224.         od;
  225.         close(chin);
  226.     corp;
  227.  
  228.     Note that this program assumes that file "NUMBERS.DAT" exists. It also
  229.     does not do any 'writeln', so the contents of the file will be one long
  230.     line. Each 'write' and 'read' could have been changed to 'writeln' and
  231.     'readln', forcing each number to a separate line.
  232.